package com.doupi.partner.op.controller;

import com.doupi.partner.dal.model.Administrator;
import com.doupi.partner.manager.authenticator.util.PasswordUtils;
import com.doupi.partner.model.PartnerRelation;
import com.doupi.partner.op.util.OpUtils;
import com.doupi.partner.service.AdministratorService;
import com.doupi.partner.service.PartnerRelationService;
import com.doupi.partner.service.dto.AdministratorDto;
import com.doupi.partner.util.AjaxResponse;
import com.doupi.partner.util.AssertUtils;
import com.doupi.partner.util.HttpRequestUtils;
import com.doupi.partner.util.constant.UtilConstants;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * 登录登出controller
 */
@Controller
public class AdminController {
	private static final String UNKNOWN_ACCOUNT_EXCEPTION_CLASS_NAME = "org.apache.shiro.authc.UnknownAccountException";
	private static final String INCORRECT_CREDENTIALS_EXCEPTION_CLASS_NAME = "org.apache.shiro.authc.IncorrectCredentialsException";
	private static final String CAPTCHA_INVALID_EXCEPTION_CLASS_NAME = "com.doupi.partner.manager.authenticator.exception.CaptchaInvalidException";
	private static final String LOCKED_ACCOUNT_EXCEPTION_CLASS_NAME = "org.apache.shiro.authc.LockedAccountException";
	private static final String AUTHENTICATION_EXCEPTION_CLASS_NAME = "org.apache.shiro.authc.AuthenticationException";
	private static final String ERROR_MESSAGE_KEY = "errorMessage";

	private final AdministratorService administratorService;

	private final PartnerRelationService partnerRelationService;

	@Autowired
	public AdminController(AdministratorService administratorService, PartnerRelationService partnerRelationService) {
		this.administratorService = administratorService;
		this.partnerRelationService = partnerRelationService;
	}

	@RequestMapping(value = { "admin_index", "/", "login" }, method = RequestMethod.GET)
	public String goAdminLogin(ModelMap modelMap, String openId) {
		modelMap.put("openId", openId);

		String returnPage = "admin_index";
		Administrator administrator = OpUtils.getCurrentLoginAdministrator();
		if (administrator != null) {
			returnPage = "admin_main";
		}
		return returnPage;
	}

	@RequestMapping(value = "auto_login")
	public String autoLoginByOpenId(HttpServletRequest httpRequest, String openId) {
		Administrator administrator = OpUtils.getCurrentLoginAdministrator();
		AssertUtils.assertNotNull(administrator, "自动登录失败");
		WebUtils.setSessionAttribute(httpRequest, "auto_login", "1");
		return "redirect:" + HttpRequestUtils.getWebRoot(httpRequest) + "/admin_index?openId=" + openId;
	}

	@RequestMapping(value = { "/", "admin_index", "login" }, method = RequestMethod.POST)
	public String doAdminLogin(HttpServletRequest httpRequest, ModelMap modelMap, String mobile, String password, String openId) {
		String exceptionClassName = (String) httpRequest.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);

		if (exceptionClassName != null) {
			modelMap.put("mobile", mobile);
			modelMap.put("password", password);
			modelMap.put("openId", openId);
			switch (exceptionClassName) {
			case CAPTCHA_INVALID_EXCEPTION_CLASS_NAME:
				modelMap.put(ERROR_MESSAGE_KEY, "验证码错误");
				break;
			case LOCKED_ACCOUNT_EXCEPTION_CLASS_NAME:
				modelMap.put(ERROR_MESSAGE_KEY, "账户被锁定，请联系管理员");
				break;
			case UNKNOWN_ACCOUNT_EXCEPTION_CLASS_NAME:

			case INCORRECT_CREDENTIALS_EXCEPTION_CLASS_NAME:
			case AUTHENTICATION_EXCEPTION_CLASS_NAME:
			default:
				modelMap.put("errorMessage", "账户或密码错误");
				break;
			}
			return "admin_index";
		} else { // 登录成功绑定微信号
			AdministratorDto administratorDto = OpUtils.getCurrentLoginAdministrator();
			if (administratorDto.isPartner() && StringUtils.isNotBlank(openId)) {
				PartnerRelation partnerRelation = partnerRelationService.selectByAdministratorId(administratorDto.getId());
				partnerRelation.setOpenId(openId);
				partnerRelationService.updateByPrimaryKeySelective(partnerRelation);
			}
		}
		return "redirect:" + HttpRequestUtils.getWebRoot(httpRequest) + "/admin_index";
	}

	@RequestMapping(value = "goUpdatePassword", method = RequestMethod.GET)
	public String goUpdatePassword() {
		return "admin_update_password";
	}

	@ResponseBody
	@RequestMapping(value = "doUpdatePassword", method = RequestMethod.POST)
	public AjaxResponse doUpdatePassword(HttpServletRequest httpRequest, String oldPassword, String newPassword) {
		AjaxResponse ajaxResponse = AjaxResponse.defaultResponse();
		Administrator administrator = (Administrator) WebUtils.getSessionAttribute(httpRequest, UtilConstants.CURRENT_USER);
		if (StringUtils.equals(administrator.getPassword(), PasswordUtils.encryptPassword(oldPassword, administrator.getPasswordSalt()))) {
			administrator.setPassword(PasswordUtils.encryptPassword(newPassword, administrator.getPasswordSalt()));
			int flag = administratorService.updateByPrimaryKeySelective(administrator);
			if (flag > 0) {
				WebUtils.setSessionAttribute(httpRequest, UtilConstants.CURRENT_USER, administrator);
			} else {
				ajaxResponse.setStatusCodeAndMessage(UtilConstants.FAIL_STATUS_CODE, "修改密码失败");
			}
		} else {
			ajaxResponse.setStatusCodeAndMessage(UtilConstants.FAIL_STATUS_CODE, "旧密码输入错误");
		}
		return ajaxResponse;
	}

	@RequestMapping("logout")
	public String logout(HttpServletRequest httpRequest, String jid) {
		if (StringUtils.equalsIgnoreCase(httpRequest.getSession().getId(), jid)) {
			SecurityUtils.getSubject().logout();
		}
		return "redirect:" + HttpRequestUtils.getWebRoot(httpRequest) + "/admin_index";
	}
}
